//go:build windows

package main

import (
	"errors"
	"gogo"
	"log"
	"sync"
	"time"

	"goodlink/pro"
	_ "goodlink/pro"
	"goodlink/theme"
	"goodlink/tools"
	"goodlink/ui2"

	_ "embed"
	_ "net/http/pprof"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/driver/desktop"
	"fyne.io/fyne/v2/layout"
	"fyne.io/fyne/v2/widget"
	"github.com/atotto/clipboard"
)

var (
	m_local_ip    string
	m_remote_addr string
	key_box       *fyne.Container
	keyValidated  *widget.Entry
	myWindow      fyne.Window
	m_start_mg    sync.WaitGroup
	m_start_lock  sync.Mutex
)

const (
	M_APP_TITLE = "GoodLink"
)

func LogInit(log_view *ui2.LogLabel) {
	gogo.Log().RegistInfo(func(content string) {
		ui2.SetLogLabel(content)
		log.Println(content)
	})
	gogo.Log().RegistDebug(func(content string) {
		ui2.SetLogLabel(content)
	})
	gogo.Log().RegistError(func(content string) {
		ui2.SetLogLabel(content)
		fyne.LogError("error: ", errors.New(content))
	})
}

func main() {
	myApp := app.New()
	myApp.Settings().SetTheme(&theme.MyTheme{})
	icon, _ := fyne.LoadResourceFromPath("./theme/favicon.png")
	myApp.SetIcon(icon)
	myWindow = myApp.NewWindow(M_APP_TITLE)

	if desk, ok := myApp.(desktop.App); ok {
		m := fyne.NewMenu(M_APP_TITLE,
			fyne.NewMenuItem("Show", func() {
				myWindow.Show()
			}))
		desk.SetSystemTrayMenu(m)
	}

	keyValidated = widget.NewEntry()
	keyValidated.SetPlaceHolder("自定义16-24字节长度")

	key_create_button := widget.NewButton("生成密钥", func() {
		keyValidated.SetText(tools.RandomString(24))
	})
	key_copy_button := widget.NewButton("复制密钥", func() {
		clipboard.WriteAll(keyValidated.Text)
	})
	key_paste_button := widget.NewButton("粘贴密钥", func() {
		if s, err := clipboard.ReadAll(); err == nil {
			keyValidated.SetText(s)
		}
	})

	localUI := ui2.NewLocalUI(&myWindow)
	localUI_Container := localUI.GetContainer()

	remoteUI := ui2.NewRemoteUI(&myWindow)
	remoteUI_Container := remoteUI.GetContainer()

	radio := widget.NewRadioGroup([]string{"Remote", "Local"}, nil)
	radio.OnChanged = func(value string) {
		switch value {
		case "Remote":
			localUI_Container.Hide()
			remoteUI_Container.Show()
		case "Local":
			remoteUI_Container.Hide()
			localUI_Container.Show()
		default:
			radio.SetSelected("Local")
		}
	}
	radio.SetSelected("Local")
	radio.Horizontal = true

	log_view := ui2.NewLogLabel("等待启动")
	LogInit(log_view)

	start_button_stats := 0
	start_button_activity := widget.NewActivity()
	start_button := widget.NewButton("点击启动", nil)
	start_button.OnTapped = func() {
		m_start_lock.Lock()
		defer m_start_lock.Unlock()

		switch start_button_stats {
		case 0:
			start_button.Disable()
			radio.Disable()
			keyValidated.Disable()
			localUI.Disable()
			key_create_button.Disable()
			key_paste_button.Disable()
			start_button_activity.Start()
			start_button_activity.Show()
			log_view.SetText("正在启动...")
			start_button_stats = 1

			go func() {
				time.Sleep(time.Second * 1)
				start_button.Enable()

				for start_button_stats == 1 {
					if pro.GetLocalStats() == 2 {
						log_view.SetText("连接成功")
						break
					}
					time.Sleep(time.Millisecond * 200)
				}
			}()

			switch radio.Selected {
			case "Local":
				m_start_mg.Add(1)
				go func() {
					defer m_start_mg.Done() // Goroutine 完成时调用 Done()
					remote_addr, err := localUI.GetRemoteAddr()
					if err != nil {
						ui2.SetLogLabel(err.Error())
						start_button_stats = 0
						return
					}
					if err := pro.RunLocal(localUI.GetConnType(), remote_addr, keyValidated.Text); err != nil {
						ui2.SetLogLabel(err.Error())
						start_button_stats = 0
						return
					}
				}()
			}

		case 1:
			start_button.Disable()
			log_view.SetText("正在停止...")
			start_button_stats = 0

			switch radio.Selected {
			case "Local":
				go func() {
					pro.StopLocal()

					radio.Enable()
					keyValidated.Enable()
					localUI.Enable()
					key_create_button.Enable()
					key_paste_button.Enable()
					start_button_activity.Stop()
					start_button_activity.Hide()
					log_view.SetText("正在启动...")
				}()
			}
		}
	}
	start_button.Importance = widget.HighImportance
	start_button.Resize(fyne.NewSize(100, 40))
	start_button.Disable()
	go func() {
		pro.Init("", "", 0)
		start_button.Enable()
	}()

	myWindow.SetContent(container.New(layout.NewVBoxLayout(),
		container.New(layout.NewFormLayout(), widget.NewRichTextWithText("工作端侧: "), radio),
		container.New(layout.NewFormLayout(), widget.NewRichTextWithText("连接密钥: "), keyValidated),
		container.NewGridWithColumns(3, key_create_button, key_copy_button, key_paste_button),
		localUI_Container, remoteUI_Container,
		container.New(layout.NewFormLayout(), widget.NewRichTextWithText("当前状态: "), log_view),
		container.NewStack(start_button, start_button_activity)))

	myWindow.SetCloseIntercept(func() {
		myWindow.Hide()
	})
	myWindow.ShowAndRun()
}
